package net.ib.mtalk.database.helper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.protobuf.micro.InvalidProtocolBufferMicroException;

import net.ib.mntalk.protocol.Common;
import net.ib.mntalk.protocol.Common.BuddyInfo;
import net.ib.mntalk.protocol.Common.ContactEntry;
import net.ib.mntalk.protocol.Common.UUIDMsg;
import net.ib.mntalk.protocol.Session.GetBuddyInfosRes;
import net.ib.mntalk.protocol.Session.SetBuddyInfoReq;
import net.ib.mntalk.protocol.client.Database.ReceiverList;
import net.ib.mtalk.database.DatabaseContract.BuddyTable;
import net.ib.mtalk.database.DatabaseContract.ContactTable;
import net.ib.mtalk.global.GlobalPreferences;
import net.ib.mtalk.ui.chat.ChatQuickActionItem;
import net.ib.mtalk.util.GpbSupport;
import net.ib.mtalk.util.MTalkLogWriter;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;

public class BuddyDatabaseHelper {
	
	public static final char HANGUL_BEGIN_UNICODE = 44032; // 가
	public static final char HANGUL_END_UNICODE = 55203; // 힣
	public static final char HANGUL_BASE_UNIT = 588;//각자음 마다 가지는 글자수
	public static final char[] INITIAL_SOUND = { 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ',
        'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' };
	
	/**
	 * updateGetBuddies
	 * @param GetBuddyInfosRes - getBuddyInfosRes
	 */
	public static void updateGetBuddy(Context context, BuddyInfo buddyInfo){
		ContentValues cv = new ContentValues();
		cv.put(BuddyTable.KEY_BUDDY_STATUS_TYPE, buddyInfo.getBuddyStatus());
		cv.put(BuddyTable.KEY_BUDDY_INFO, buddyInfo.toByteArray());
		cv.put(BuddyTable.KEY_BUDDY_DISPLAYNAME, buddyInfo.getName().getDisplayName());
		cv.put(BuddyTable.KEY_BUDDY_DISPLAYNICK, buddyInfo.getNick().getDisplayName());
		ContentResolver cr = context.getContentResolver();
		String where = BuddyTable.KEY_BUDDY_UUID_MSB + "=? AND " + BuddyTable.KEY_BUDDY_UUID_LSB + "=?";
		String[] selectionArgs = {String.valueOf(GpbSupport.msbOf(buddyInfo.getUserUuid())), String.valueOf(GpbSupport.lsbOf(buddyInfo.getUserUuid()))};
		cr.update(BuddyTable.CONTENT_URI, cv, where, selectionArgs);
	}
	
	/**
	 * insertGetBuddies
	 * @param GetBuddyInfosRes - getBuddyInfosRes
	 */
	public static void insertGetBuddies(Context context, GetBuddyInfosRes getBuddyInfosRes){
		BuddyInfo buddyInfo;
		ContactEntry entry;
		ContentValues cv  = new ContentValues();
		ContentValues cv_contact  = new ContentValues();
		if(getBuddyInfosRes.hasNotiUuid()){
			GlobalPreferences.setLastBuddyChangedNotiUUID(getBuddyInfosRes.getNotiUuid());
		}
		for(int i = 0 ; i < getBuddyInfosRes.getBuddyInfoCount(); i ++){
			cv.clear();
			buddyInfo = getBuddyInfosRes.getBuddyInfo(i);
			
			Cursor cursor = context.getContentResolver().query(BuddyTable.CONTENT_URI, BuddyTable.PROJECTION, BuddyTable.KEY_BUDDY_UUID_MSB + "=? AND " + BuddyTable.KEY_BUDDY_UUID_LSB + "=?"
					, new String[]{String.valueOf(GpbSupport.msbOf(buddyInfo.getUserUuid())), String.valueOf(GpbSupport.lsbOf(buddyInfo.getUserUuid()))}, null);
			try{
				if(cursor.getCount() > 0){
					updateGetBuddy(context, buddyInfo);
					continue;
				}
			} finally {
				cursor.close();
			}
			cv.put(BuddyTable.KEY_BUDDY_UUID_MSB, GpbSupport.msbOf(buddyInfo.getUserUuid()));
			cv.put(BuddyTable.KEY_BUDDY_UUID_LSB, GpbSupport.lsbOf(buddyInfo.getUserUuid()));
			cv.put(BuddyTable.KEY_BUDDY_STATUS_TYPE, buddyInfo.getBuddyStatus()==0 ? 1 : buddyInfo.getBuddyStatus());
			cv.put(BuddyTable.KEY_BUDDY_INFO, buddyInfo.toByteArray());
			cv.put(BuddyTable.KEY_BUDDY_DISPLAYNAME, buddyInfo.getName().getDisplayName() == null ? " ": buddyInfo.getName().getDisplayName());	
			cv.put(BuddyTable.KEY_BUDDY_DISPLAYNICK, buddyInfo.getNick().getDisplayName() == null ? " ": buddyInfo.getNick().getDisplayName());
			cv.put(BuddyTable.KEY_BUDDY_CHOSUNG, insertChosung(buddyInfo.getNick().getDisplayName()));
			cv.put(BuddyTable.KEY_BUDDY_NEW_FRIEND, 1);	
			ContentResolver cr = context.getContentResolver();
			cr.insert(BuddyTable.CONTENT_URI, cv);
			
			for(int j = 0 ; j < buddyInfo.getContactsCount() ; j++){
				entry = buddyInfo.getContacts(j);
				cv_contact.clear();
				cv_contact.put(ContactTable.KEY_BUDDY_UUID_MSB, GpbSupport.msbOf(buddyInfo.getUserUuid()));
				cv_contact.put(ContactTable.KEY_BUDDY_UUID_LSB, GpbSupport.lsbOf(buddyInfo.getUserUuid()));
				
				context.getContentResolver().update(ContactTable.CONTENT_URI, cv_contact, ContactTable.KEY_CONTACT_IDENTIFIER + "=?", new String[]{entry.getAccountId().getIdentifier()});
			}
		}
		if(getBuddyInfosRes.hasNotiUuid()){
			GlobalPreferences.setLastBuddyChangedNotiUUID(getBuddyInfosRes.getNotiUuid());
		}
	}
	
	private static String insertChosung(String displayName) {
		String chosung = "";
		char cho;
		char afterCho;
		for(int i=0; i < displayName.length(); i++){
			cho = displayName.charAt(i);
			if(cho < HANGUL_BEGIN_UNICODE){
				afterCho = cho;
			} else {
				afterCho = INITIAL_SOUND[(cho-HANGUL_BEGIN_UNICODE)/HANGUL_BASE_UNIT];
			}
			chosung += afterCho;
		}
		return chosung;
	}

	public static void removeAllBuddy(Context context)
	{
		ContentResolver cr = context.getContentResolver();
		cr.delete(BuddyTable.CONTENT_URI, null, null);
	}

	/**
	 * insertFavorite
	 * @param Context - context
	 * @param UUIDMsg - msg
	 */
	public static void insertFavorite(Context context, UUIDMsg msg) {
		ContentValues cv = new ContentValues();
		cv.put(BuddyTable.KEY_BUDDY_FAVORITE, 1);
		String where = BuddyTable.KEY_BUDDY_UUID_MSB + "=? AND " + BuddyTable.KEY_BUDDY_UUID_LSB + "=?";
		String[] selectionArgs = {String.valueOf(GpbSupport.msbOf(msg)), String.valueOf(GpbSupport.lsbOf(msg))};
		context.getContentResolver().update(BuddyTable.CONTENT_URI, cv, where, selectionArgs);
	}
	
	/**
	 * removeFavorite
	 * @param Context - context
	 * @param UUIDMsg - msg
	 */
	public static void removeFavorite(Context context, UUIDMsg msg) {
		ContentValues cv = new ContentValues();
		cv.put(BuddyTable.KEY_BUDDY_FAVORITE, 0);
		String where = BuddyTable.KEY_BUDDY_UUID_MSB + "=? AND " + BuddyTable.KEY_BUDDY_UUID_LSB + "=?";
		String[] selectionArgs = {String.valueOf(GpbSupport.msbOf(msg)), String.valueOf(GpbSupport.lsbOf(msg))};
		context.getContentResolver().update(BuddyTable.CONTENT_URI, cv, where, selectionArgs);
	}
	
	/**
	 * blockBuddy
	 * @param Context - context
	 * @param UUIDMsg - msg
	 */
	public static void updateBuddyStatus(Context context, SetBuddyInfoReq setBuddyInfoReq) {
		ContentValues cv = new ContentValues();
		cv.put(BuddyTable.KEY_BUDDY_INFO, setBuddyInfoReq.getBuddyInfo().toByteArray());
		cv.put(BuddyTable.KEY_BUDDY_STATUS_TYPE, setBuddyInfoReq.getBuddyInfo().getBuddyStatus());
		String where = BuddyTable.KEY_BUDDY_UUID_MSB + "=? AND " + BuddyTable.KEY_BUDDY_UUID_LSB + "=?";
		UUIDMsg msg = setBuddyInfoReq.getBuddyInfo().getUserUuid();
		String[] selectionArgs = {String.valueOf(GpbSupport.msbOf(msg)), String.valueOf(GpbSupport.lsbOf(msg))};
		context.getContentResolver().update(BuddyTable.CONTENT_URI, cv, where, selectionArgs);
	}

	/**
	 * removeBuddy
	 * @param Context - context
	 * @param UUIDMsg - msg
	 */
	/*public static void removeBuddy(Context context,SetBuddyInfoReq setBuddyInfoReq) {
		ContentValues cv = new ContentValues();
		cv.put(BuddyTable.KEY_BUDDY_INFO, setBuddyInfoReq.getBuddyInfo().toByteArray());
		cv.put(BuddyTable.KEY_BUDDY_STATUS_TYPE, setBuddyInfoReq.getBuddyInfo().getBuddyStatus());
		String where = BuddyTable.KEY_BUDDY_UUID_MSB + "=? AND " + BuddyTable.KEY_BUDDY_UUID_LSB + "=?";
		UUIDMsg msg = setBuddyInfoReq.getBuddyInfo().getUserUuid();
		String[] selectionArgs = {String.valueOf(GpbSupport.msbOf(msg)), String.valueOf(GpbSupport.lsbOf(msg))};
		int i = context.getContentResolver().update(BuddyTable.CONTENT_URI, cv, where, selectionArgs);
	}*/
	
	public static Cursor selectRemoveBuddy(Context context)
	{
		return context.getContentResolver().query(
				BuddyTable.CONTENT_URI, 
				null, 
				BuddyTable.KEY_BUDDY_STATUS_TYPE + "=" + Common.BUDDY_STATUS_DELETE, 
				null, BuddyTable.KEY_BUDDY_DISPLAYNAME);
	}
	
	public static Cursor selectBlockBuddy(Context context)
	{
		return context.getContentResolver().query(
				BuddyTable.CONTENT_URI, 
				null, 
				BuddyTable.KEY_BUDDY_STATUS_TYPE + "=" + Common.BUDDY_STATUS_BLOCK, 
				null, BuddyTable.KEY_BUDDY_DISPLAYNAME);
	}
	
	/**
	 * ReceiverList 의 이름을 추출하여 보여준다. 
	 * @author happy2v
	 */
	public static String getReceiverName(Context context, ReceiverList receiverList){
		String name = "";
		
		String where = "";
		String sortOrder = BuddyTable.KEY_BUDDY_DISPLAYNAME;
		
		if(receiverList.getReceiverCount()==0){
			return " ";
		}
		
		for(int i = 0; i < receiverList.getReceiverCount(); i++){
			if(i == 0){
				where = "(" + BuddyTable.KEY_BUDDY_UUID_MSB + "=" + GpbSupport.msbOf(receiverList.getReceiver(i).getUserUuid())
				+ " AND "
				+ BuddyTable.KEY_BUDDY_UUID_LSB + "=" + GpbSupport.lsbOf(receiverList.getReceiver(i).getUserUuid()) + ")";
			}else{
				where = where + " OR " 
				+ "(" + BuddyTable.KEY_BUDDY_UUID_MSB + "=" + GpbSupport.msbOf(receiverList.getReceiver(i).getUserUuid())
				+ " AND "
				+ BuddyTable.KEY_BUDDY_UUID_LSB + "=" + GpbSupport.lsbOf(receiverList.getReceiver(i).getUserUuid()) + ")";
			}
		}
		
		ContentResolver cr = context.getContentResolver();
		
		Cursor nameCursor = cr.query(BuddyTable.CONTENT_URI, new String[]{BuddyTable.KEY_BUDDY_DISPLAYNAME}, 
				where, null, sortOrder);
		
		try{
			if(nameCursor.moveToFirst()){
				name = nameCursor.getString(nameCursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_DISPLAYNAME));
			}
			while(nameCursor.moveToNext()){
				name = name + ", " + nameCursor.getString(nameCursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_DISPLAYNAME));
			}
		}finally{
			nameCursor.close();
		}
		
		return name;
	}
	
	/**
	 * ChatList Profile 클릭시 QuickAction을 위해 정보를 읽어 간다.
	 * @param buddyUuid
	 * @author happy2v
	 */
	public static ChatQuickActionItem getChatBuddyInfo(Context context, UUIDMsg buddyUuid){
		ChatQuickActionItem item = null;
		String[] projection = new String[]{ContactTable.KEY_CONTACT_PHONE_ID, BuddyTable._ID, 
				BuddyTable.KEY_BUDDY_DISPLAYNAME, BuddyTable.KEY_BUDDY_INFO, BuddyTable.KEY_BUDDY_FAVORITE};
		String selection = BuddyTable.KEY_BUDDY_UUID_MSB + "=? AND " + BuddyTable.KEY_BUDDY_UUID_LSB + "=?";
		String[] selectionArgs = new String[]{String.valueOf(GpbSupport.msbOf(buddyUuid)), String.valueOf(GpbSupport.lsbOf(buddyUuid))};
		
		ContentResolver cr = context.getContentResolver();
		
		Cursor itemCursor = cr.query(ContactTable.buildContactBuddy(), projection, selection, selectionArgs, null);
		
		try{
			if(itemCursor.moveToFirst()){
				try {
					int raw_id = -1;
					if(itemCursor.getInt(itemCursor.getColumnIndexOrThrow(ContactTable.KEY_CONTACT_PHONE_ID)) != 0){
						raw_id = itemCursor.getInt(itemCursor.getColumnIndexOrThrow(ContactTable.KEY_CONTACT_PHONE_ID));
					}
					item = new ChatQuickActionItem(
							itemCursor.getInt(itemCursor.getColumnIndexOrThrow(BuddyTable._ID)),
							GpbSupport.msbOf(buddyUuid),
							GpbSupport.lsbOf(buddyUuid),
							itemCursor.getString(itemCursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_DISPLAYNAME)),
							BuddyInfo.parseFrom(itemCursor.getBlob(itemCursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_INFO))),
							raw_id,
							itemCursor.getInt(itemCursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_FAVORITE)));
				} catch (IllegalArgumentException e) {
					MTalkLogWriter.e(e);
				} catch (InvalidProtocolBufferMicroException e) {
					MTalkLogWriter.e(e);
				}
			}
		}finally{
			itemCursor.close();
		}
		
		return item;
	}
	
	/**
	 * removeBuddy
	 * @param Context - context
	 * @param UUIDMsg - buddyUUID
	 */
	public static void removeBuddy(Context context, UUIDMsg buddyUUID) {
		String where = BuddyTable.KEY_BUDDY_UUID_MSB + "=? AND " + BuddyTable.KEY_BUDDY_UUID_LSB + "=?";
		String[] selectionArgs = {String.valueOf(GpbSupport.msbOf(buddyUUID)), String.valueOf(GpbSupport.lsbOf(buddyUUID))};
		context.getContentResolver().delete(BuddyTable.CONTENT_URI, where, selectionArgs);
		
	}

	/**
	 * updateBuddyImage
	 * @param Context - context
	 * @param UUIDMsg - profileUuid
	 */
	public static void updateBuddyImage(Context context, UUIDMsg profileUuid, boolean inite) {
		ContentValues cv = new ContentValues();
		if(inite){
			cv.put(BuddyTable.KEY_BUDDY_IMG_VERSION, 0);
		} else{
			cv.put(BuddyTable.KEY_BUDDY_IMG_VERSION, 1);
		}
		String where = BuddyTable.KEY_BUDDY_UUID_MSB + "=? AND " + BuddyTable.KEY_BUDDY_UUID_LSB + "=?";
		String[] selectionArgs = {String.valueOf(GpbSupport.msbOf(profileUuid)), String.valueOf(GpbSupport.lsbOf(profileUuid))};
		context.getContentResolver().update(BuddyTable.CONTENT_URI, cv, where, selectionArgs);
		
	}

	/**
	 * getBuddyNumber
	 * @param context
	 * @return
	 */
	public static Map<String, UUIDMsg> getBuddyNumber(Context context) {
		Cursor cursor = context.getContentResolver().query(BuddyTable.CONTENT_URI, BuddyTable.PROJECTION, null, null, null);
		Map<String, UUIDMsg> map = new HashMap<String, Common.UUIDMsg>();
		try{
			while (cursor.moveToNext()) {
				BuddyInfo buddyInfo = BuddyInfo.parseFrom(cursor.getBlob(cursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_INFO)));
				for(int i=0;i<buddyInfo.getContactsCount();i++){
					map.put(buddyInfo.getContacts(i).getAccountId().getIdentifier(), buddyInfo.getUserUuid());
				}
			}
		} catch (InvalidProtocolBufferMicroException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} finally{
			cursor.close();
		}
		return map;
	}
}
